package com.xuecheng.search;

import com.mongodb.QueryBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.fetch.subphase.highlight.Highlighter;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.Map;

/**
 * @author 冯志立
 * @create 2019-12-12 12:18
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class TESTSearch {
    @Autowired
    private RestHighLevelClient highLevelClient;

    @Autowired
    private RestClient restClient;

    @Test
    public void testSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("xc_course");

        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        //包括的字段和不包括的字段
        searchSourceBuilder.fetchSource(new String[]{"name","description"}, new String[]{});
        searchRequest.source(searchSourceBuilder);

        SearchResponse search = highLevelClient.search(searchRequest);
        SearchHits hits = search.getHits();
        long totalHits = hits.getTotalHits();
        //得到匹配度高的文档
        SearchHit[] hits1 = hits.getHits();
        for (SearchHit hit:hits1) {
            //文档住建
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            //注意源文档的字段过滤
            String description = (String) sourceAsMap.get("description");
        }
    }

    @Test
    public void testPage() throws IOException {
        SearchRequest searchRequest = new SearchRequest("xc_course");

        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        int page = 1;
        int size = 1;
        //计算出记录的起始下标
        int from = (page -1) * size;
        searchSourceBuilder.from(from); //起始记录下标
        searchSourceBuilder.size(size); //每页显示记录数

        searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        //包括的字段和不包括的字段
        searchSourceBuilder.fetchSource(new String[]{"name","description"}, new String[]{});
        searchRequest.source(searchSourceBuilder);

        SearchResponse search = highLevelClient.search(searchRequest);
        SearchHits hits = search.getHits();
        long totalHits = hits.getTotalHits();   //得到的总数
        //得到匹配度高的文档
        SearchHit[] hits1 = hits.getHits();   //显示的个数
        for (SearchHit hit:hits1) {
            //文档住建
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            //注意源文档的字段过滤
            String description = (String) sourceAsMap.get("description");
        }
    }

    @Test
    public void testTerm() throws IOException {
        SearchRequest searchRequest = new SearchRequest("xc_course");

        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        int page = 1;
        int size = 1;
        //计算出记录的起始下标
        int from = (page -1) * size;
        searchSourceBuilder.from(from); //起始记录下标
        searchSourceBuilder.size(size); //每页显示记录数
        String[] strings = new String[]{"1","2","3"};
        searchSourceBuilder.query(QueryBuilders.termsQuery("_id", strings));   //根据项的查询

        //包括的字段和不包括的字段
        searchSourceBuilder.fetchSource(new String[]{"name","description"}, new String[]{});
        searchRequest.source(searchSourceBuilder);

        SearchResponse search = highLevelClient.search(searchRequest);
        SearchHits hits = search.getHits();
        long totalHits = hits.getTotalHits();   //得到的总数
        //得到匹配度高的文档
        SearchHit[] hits1 = hits.getHits();   //显示的个数
        for (SearchHit hit:hits1) {
            //文档住建
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            //注意源文档的字段过滤
            String description = (String) sourceAsMap.get("description");
        }
    }

    @Test
    public void testMulTerm() throws IOException {
        SearchRequest searchRequest = new SearchRequest("xc_course");

        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        int page = 1;
        int size = 1;
        //计算出记录的起始下标
        int from = (page -1) * size;
        searchSourceBuilder.from(from); //起始记录下标
        searchSourceBuilder.size(size); //每页显示记录数
        String[] strings = new String[]{"1","2","3"};
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("_id", strings).minimumShouldMatch("80%").field("name", 10));   //根据项的查询
        searchSourceBuilder.sort("studymodel", SortOrder.DESC);
        searchSourceBuilder.sort("price", SortOrder.ASC);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<tag>");
        highlightBuilder.postTags("</tag>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));

        //包括的字段和不包括的字段
        searchSourceBuilder.fetchSource(new String[]{"name","description"}, new String[]{});
        searchRequest.source(searchSourceBuilder);

        SearchResponse search = highLevelClient.search(searchRequest);
        SearchHits hits = search.getHits();
        long totalHits = hits.getTotalHits();   //得到的总数
        //得到匹配度高的文档
        SearchHit[] hits1 = hits.getHits();   //显示的个数
        for (SearchHit hit:hits1) {
            //文档住建
            String id = hit.getId();
            //源文档内容
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (highlightFields != null){
                HighlightField name1 = highlightFields.get("name");
                if (name1 != null){
                    Text[] fragments = name1.getFragments();
                    StringBuffer stringBuffer = new StringBuffer();

                    for (Text f:fragments) {
                        stringBuffer.append(f);
                    }
                }
            }
            //注意源文档的字段过滤
            String description = (String) sourceAsMap.get("description");
        }
    }
}
